package main

import (
	"encoding/binary"
	"fmt"
	"net"
)

func main() {
	fmt.Println("这是一个简单的服务器，用户发一个0x01请求，返回客户端的IP+端口")
	fmt.Println("Listening on 0.0.0.0:9999")
	listener, err := net.Listen("tcp", "0.0.0.0:9999")
	if err != nil {
		fmt.Println("错误，无法启动监听")
		return
	}
	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				break
			}
			go DoClient(conn)
		}
	}()

	select {}
}

func DoClient(conn net.Conn) {
	defer conn.Close()
	var buf = make([]byte, 512)
	cnt, err := conn.Read(buf)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	if cnt < 4 {
		fmt.Println("消息格式为[uint16-长度][uint16-msgId][可选的额外内容]，至少要4个字节")
		return
	}

	bufRead := buf[0:cnt]
	fmt.Println("收到数据(byte []):", bufRead)
	// 使用网络字节序，即大尾数
	msgLen := binary.BigEndian.Uint16(bufRead)
	if msgLen != uint16(cnt)-2 {
		fmt.Printf("长度错误。%d-%d\n", msgLen, uint16(cnt)-2)
		return
	}

	msgId := binary.BigEndian.Uint16(bufRead[2:])
	switch msgId {
	case 0x0001:
		fmt.Println("收到了返回客户端IP的消息")
		strRAddr := conn.RemoteAddr().String()
		fmt.Println("对方IP地址:", strRAddr)

		var sndBuf = make([]byte, 256)
		dataLen := len(strRAddr) + 2
		binary.BigEndian.PutUint16(sndBuf, uint16(dataLen))
		binary.BigEndian.PutUint16(sndBuf[2:], 0x0001)
		copy(sndBuf[4:], []byte(strRAddr))
		fmt.Println("发送数据(byte []):", sndBuf[:dataLen+2])
		conn.Write(sndBuf[:dataLen+2])
	default:
		fmt.Println("未知的消息")
		return
	}
}
